//============================================================================
// Name        : tp0.cpp
// Author      : 
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
#include <string>
#include "TiposComunes.h"
#include "ConfigurationManager/ConfigurationManager.h"
#include "DataStructures/ArchivodeBloques.h"
#include "FileAccess/ArchivoBinario.h"
#include "DataStructures/Bloque.h"


struct Data{
	unsigned int id;
	char  Description[40];
	unsigned int tamanio() const{
		return sizeof(id) + strlen(Description)+1;
	}
	bool operator==(const Data&otro){
		return id==otro.id;
	}
	std::ostream& operator<<(std::ostream& out)
	{
	  return out<< id;
	}
};

template <typename CharT, typename Traits>
std::basic_ostream<CharT, Traits>& operator<<(
  std::basic_ostream<CharT, Traits>& out, const Data& data)
{
  return out<< data.id << ": " << data.Description;
}


/*
class Data : public RegistroVariable{
//private:
public:
	int id;
	std::string Description;

	Data(){
		id=0;
		Description="";
	}

	Data(const RegistroVariable & Comp){
		id=((Data)Comp).id;
		Description=((Data)Comp).Description;
	}
	unsigned int size() const{
	return sizeof(id) + Description.length();
	}
	bool operator==(const RegistroVariable& Comp) const{
		return ((Data)Comp).id == this->id;
	}
	bool operator!=(const RegistroVariable& Comp) const{
		return !(*this==Comp);
	}
	bool operator<(const RegistroVariable& Comp) const{
		return false;
		}

		bool operator>(const RegistroVariable& Comp) const{
			return !(*this < Comp);
		}
		bool operator<=(const RegistroVariable& Comp) const{
			return true;
		}

		bool operator>=(const RegistroVariable& Comp) const{
			return !(*this<Comp);
		}
};

*/
/*
struct Data{
	int id;
	std::string Description;
	bool operator==(const Data & otro){
		return otro.id == this->id;
	}
	std::ostream& operator<<(std::ostream& out) // output
	{RegistroVariable
	    out << this->id << " (" << this->Description << ")";
	    return out;
	}
	std::istream& operator>>(std::istream& in) // output
	{
		std::cout << "Ingrese el identificador del nuevo registro (int): ";
		in >> this->id;
		std::cout << "Ingrese la descripcion del nuevo registro (string): ";
		in >> this->Description;
		return in;
	}
};
*/


void listFileContent( ArchivodeBloques<Data> & archivo){
	archivo.listarContenido(std::cout);
}

void insertrecord( ArchivodeBloques<Data> & archivo){

	Data nuevoDato;

	nuevoDato.id = 347;
	strcpy(nuevoDato.Description,"hola que tal!\0");

	archivo.agregarRegistro(nuevoDato,nuevoDato.tamanio());

	listFileContent(archivo);


}
void deleterecord(ArchivodeBloques<Data> & archivo){
	OPERACIONBLOQUE res;
	Data  registro;
	archivo.eliminarRegistro(registro, res);
	listFileContent(archivo);
}
void modifyrecord( ArchivodeBloques<Data> & archivo){
	OPERACIONBLOQUE resultado;
	Data  registro;
	archivo.actualizarRegistro(registro,registro.tamanio(), resultado);
	if (resultado == FALLA)
		std::cout << "Falla en actualizacion " << registro.id << " (" << registro.Description << ")";
	else
		std::cout << "Update OK " << registro.id << " (" << registro.Description << ")";

	listFileContent(archivo);

}

int main(int argc, char **argv) {




	ConfigurationSettings config(argv[0]);
	ArchivodeBloques<Data> archivo(argv[0]);

	std::string path = argv[0];
    path+=".dat";



    char op=0;
    do{
    	std::system("clear");
    	std::cout << "ADMINISTRADOR DE ARCHIVOS\n\n";
    	std::cout << "Trabajando con el archivo de datos: " << path <<"\n\n";

    	std::cout << "MENU OPTIONS\n";
    	std::cout << "A: Alta de Nuevo registro\n";
    	std::cout << "B: Baja de registro\n";
    	std::cout << "M: Modificacion registro\n";
    	std::cout << "S: Salir del programa\n";
    	std::cin >> op;

        switch (op){
        case 'A':
			insertrecord(archivo);
			break;
        case 'B':
        	deleterecord(archivo);
        	break;
        case 'M':
        	modifyrecord(archivo);
        	break;
        case 'S':
        	std::cout << "Saliendo...";
        	break;
        default:
    			std::cout << "opcion invalida";
        }


    }while (op!='S');


    return 0;
}


